import {
  FullscreenExitOutlined,
  FullscreenOutlined,
  LeftOutlined,
  MinusCircleOutlined,
  PlusCircleOutlined,
  RightOutlined,
} from '@ant-design/icons';
import { Input, Spin, Tooltip } from 'antd';
import React, { useCallback, useEffect, useRef, useState } from 'react';

import { EmptyEle } from '@/components/EmptyEle';
import { useMount, useSize } from 'ahooks';
import { Document, Page, pdfjs } from 'react-pdf';
import styled from 'styled-components';
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

const FileViewLayout = styled.div`
  &.preview {
    position: relative;
    width: 100%;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    background-color: var(--white-color);

    .react-pdf__Document {
      width: 100%;
    }
    .react-pdf__Page {
      width: 100%;
      /* box-shadow: 0 0 0 10px var(--content-bg-color); */
      &:not(:last-child) {
        margin-bottom: 10px;
      }
    }
    .react-pdf__Page__svg,
    .react-pdf__Page__canvas {
      margin: 0 auto;
      fill: none;
      stroke: none;
    }

    .pageContainer {
      width: max-content;
      width: 100%;
      max-width: 100%;
      margin: 0 auto;
    }
    .pageTool {
      position: fixed;
      bottom: 40px;
      left: 50%;
      z-index: 999;
      transform: translateX(-50%);
      padding: 8px 15px;
      color: white;
      background: #323639;
      border-radius: 5px;

      span {
        padding: 5px;
        margin: 0 5px;
        &:hover {
          background: #525659;
          border-radius: 4px;
        }
      }

      input {
        display: inline-block;
        width: 50px;
        height: 24px;
        margin-right: 10px;
        text-align: center;
      }
      input::-webkit-outer-spin-button,
      input::-webkit-inner-spin-button {
        -webkit-appearance: none;
      }
      input[type='number'] {
        appearance: textfield;
      }
    }
  }
`;

interface Props {
  fileUrl: string;
  /** 是否启用blob */ useBlob?: boolean;
  /** 启用分页模式浏览 */ usePagination?: boolean;
  /** 启用浏览操作功能 */ useTool?: boolean;
  /** 删除不显示最后一页 */ removeLastPage?: boolean;
}

const defState = {
  defaultWidth: 900,
  /** 初始缩放比率 */ defZoomRate: 0.8,
  /** 每次缩小比率 */ defZoomOutRate: 0.8,
  /** 每次放大比率 */ defZoomInRate: 1.2,
  /** 最小缩放比率 */ minZoomRate: 0.25,
  /** 最大缩放比率 */ maxZoomRate: 5,
};

export const PdfPreview: React.FC<Props> = (props) => {
  const { fileUrl, useBlob, usePagination, useTool, removeLastPage } = props;

  const [pdfUrl, setPdfUrl] = useState('');

  const [PDFBlob, setPDFBlob] = useState<any>();
  const ref = useRef(null);
  const { width: viewWidth = 0 } = useSize(ref) || {};

  const [numPages, setNumPages] = useState(1);
  const [pageNumber, setPageNumber] = useState(1);
  const [pageNumberInput, setPageNumberInput] = useState(1);
  const [pageNumberFocus, setPageNumberFocus] = useState(false);
  const [pageWidth, setPageWidth] = useState(0);
  const [fullscreen, setFullscreen] = useState(false);

  // 上一页
  const lastPage = () => {
    if (pageNumber === 1) {
      return;
    }
    const page = pageNumber - 1;
    setPageNumber(page);
    setPageNumberInput(page);
  };

  // 下一页
  const nextPage = () => {
    if (pageNumber === numPages) {
      return;
    }
    const page = pageNumber + 1;
    setPageNumber(page);
    setPageNumberInput(page);
  };
  const onPageNumberFocus = () => {
    setPageNumberFocus(true);
  };
  const onPageNumberBlur = () => {
    setPageNumberFocus(false);
    setPageNumberInput(pageNumber);
  };
  // 输入框输入页码
  const onPageNumberChange = (e: any) => {
    let value = e.target.value;
    value = value <= 0 ? 1 : value;
    value = value >= numPages ? numPages : value;
    setPageNumberInput(value);
  };
  // 输入框输入页码跳转
  const toPage = (e: any) => {
    setPageNumber(Number(e.target.value));
  };
  // 缩小
  const pageZoomOut = () => {
    let minPageWidth = Number((viewWidth * defState.minZoomRate).toFixed(0));

    if (pageWidth <= minPageWidth) {
      return;
    }

    let currPageWidth = Number(
      (pageWidth * defState.defZoomOutRate).toFixed(0),
    );

    setPageWidth(currPageWidth);
  };

  // 放大
  const pageZoomIn = () => {
    let maxPageWidth = Number(
      (defState.defaultWidth * defState.maxZoomRate).toFixed(0),
    );

    if (pageWidth >= maxPageWidth) {
      return;
    }

    let currPageWidth = Number((pageWidth * defState.defZoomInRate).toFixed(0));

    setPageWidth(currPageWidth);
  };

  // 适应屏幕和恢复默认
  const pageFullscreen = () => {
    if (fullscreen) {
      setFullscreen(false);
      setPageWidth(defState.defaultWidth);
    } else {
      setFullscreen(true);
      setPageWidth(viewWidth);
    }
  };

  //页面加载完回调
  const onDocumentLoadSuccess = (res: any) => {
    const { numPages } = res;
    let totalPages = removeLastPage && numPages > 1 ? numPages - 1 : numPages;
    setNumPages(totalPages);
    pageFullscreen();
  };

  //页面渲染完回调
  const onDocumentOnRenderSuccess = useCallback(() => {
    let pdfDom: any = document.getElementsByClassName('react-pdf__Page')[0];
    let width = pdfDom.offsetWidth;

    setPageWidth(width);
  }, []);

  // 转换url
  useEffect(() => {
    if (fileUrl) {
      let { protocol } = window.location;
      let url = protocol + fileUrl.split(':')[1];

      setPdfUrl(url);
    }
  }, [fileUrl]);

  // 转成blob
  //   useEffect(() => {
  //     if (pdfUrl && useBlob) {
  //       readFile(pdfUrl)
  //         .then((res) => {
  //           if (res) {
  //             setPDFBlob(res);
  //           } else {
  //             setPDFBlob(undefined);
  //           }
  //         })
  //         .catch((err) => {
  //           setPDFBlob(undefined);
  //         });
  //     }
  //   }, [pdfUrl, useBlob]);

  // 屏蔽右键菜单
  useMount(() => {
    document.oncontextmenu = (evt: any) => {
      try {
        /*屏蔽浏览器默认右键事件*/
        let e = evt || window.event;
        const elem = e.srcElement;

        // pdf使用了画面渲染，只有在画面上右键时才屏蔽，其它地方右键正常
        if (elem.tagName === 'CANVAS') {
          return false;
        }

        return true;
      } catch (e) {
        return false;
      }
    };
  });

  const PageRender = useCallback(
    (pageNumber: number) => {
      return (
        <Page
          key={pageNumber}
          pageNumber={pageNumber}
          width={pageWidth}
          loading={<Spin size="large" />}
          scale={1}
          onRenderSuccess={onDocumentOnRenderSuccess}
        />
      );
    },
    [pageWidth, onDocumentOnRenderSuccess],
  );

  return (
    <>
      {pdfUrl ? (
        <FileViewLayout ref={ref} className={'preview'}>
          <div className={'pageContainer'}>
            <Document
              file={useBlob ? PDFBlob : pdfUrl} // 文件路径 pdfUrl 可以是一个URL、File、或者包含url、data、range、httpHeaders的对象
              onLoadSuccess={onDocumentLoadSuccess} // 成功加载文档后调用
              onLoadError={console.error} // 加载失败时调用
              renderMode="canvas" // 定义文档呈现的形式
              loading={
                <div
                  style={{
                    height: document.documentElement.clientHeight - 130,
                    textAlign: 'center',
                  }}>
                  <Spin />
                </div>
              } //加载时提示语句
              externalLinkTarget="_blank"
              options={{
                // 解决预览部分字体不展示问题
                cMapUrl:
                  'https://cdn.jsdelivr.net/npm/pdfjs-dist@4.2.67/cmaps/',
                cMapPacked: true,
                disableWorker: true,
              }}>
              {usePagination
                ? PageRender(pageNumber)
                : new Array(numPages).fill(null).map((item, idx) => {
                    return PageRender(idx + 1);
                  })}
            </Document>
          </div>

          {useTool && (
            <div className={'pageTool'}>
              {usePagination && (
                <>
                  <Tooltip title={pageNumber === 1 ? '已是第一页' : '上一页'}>
                    <LeftOutlined onClick={lastPage} />
                  </Tooltip>
                  <Input
                    value={pageNumberFocus ? pageNumberInput : pageNumber}
                    onFocus={onPageNumberFocus}
                    onBlur={onPageNumberBlur}
                    onChange={onPageNumberChange}
                    onPressEnter={toPage}
                    type="number"
                  />
                  / {numPages}
                  <Tooltip
                    title={pageNumber === numPages ? '已是最后一页' : '下一页'}>
                    <RightOutlined onClick={nextPage} />
                  </Tooltip>
                </>
              )}

              <Tooltip title="放大">
                <PlusCircleOutlined onClick={pageZoomIn} />
              </Tooltip>
              <Tooltip title="缩小">
                <MinusCircleOutlined onClick={pageZoomOut} />
              </Tooltip>
              <Tooltip title={fullscreen ? '恢复默认' : '适合窗口'}>
                {fullscreen ? (
                  <FullscreenExitOutlined onClick={pageFullscreen} />
                ) : (
                  <FullscreenOutlined onClick={pageFullscreen} />
                )}
              </Tooltip>
            </div>
          )}
        </FileViewLayout>
      ) : (
        <EmptyEle />
      )}
    </>
  );
};
